package lk.icta.core.service.impl;

import lk.icta.common.ELandRuntimeException;
import lk.icta.common.ErrorCodes;
import lk.icta.common.service.DocumentManagementService;
import lk.icta.common.service.MailSenderService;
import lk.icta.core.dao.KachcheryDAO;
import lk.icta.core.dao.ScheduleDAO;
import lk.icta.core.dto.LandAssociationDetails;
import lk.icta.core.entity.AlienationMethod;
import lk.icta.core.entity.Kachchery;
import lk.icta.core.entity.LandAssociation;
import lk.icta.core.entity.Schedule;
import lk.icta.core.service.KachcheryManagementService;
import lk.icta.core.service.ScheduleManagementService;
import lk.icta.user.common.Permission;
import lk.icta.user.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author Kusal Samarakoon
 */
public class KachcheryManagementServiceImpl implements KachcheryManagementService {

    private static final Logger logger = LoggerFactory.getLogger(KachcheryManagementServiceImpl.class);
    private final KachcheryDAO kachcheryDAO;
    private final DocumentManagementService documentManagementService;

    public KachcheryManagementServiceImpl(KachcheryDAO kachcheryDAO, DocumentManagementService documentManagementService) {
        this.kachcheryDAO = kachcheryDAO;
        this.documentManagementService = documentManagementService;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void addKachchery(Kachchery kachchery, User user) {
        logger.debug("Adding a Kachchery {}", kachchery.getId());
        /*if (!user.isAuthorized(Permission.)) {
            handleELandRuntimeException(user.getUsername() + " doesn't have permission to add a kachchery", ErrorCodes.UNAUTHORIZED_ACCESS);
        } else {
            kachcheryDAO.addKachchery(kachchery, user);
        }*/
        try {
            kachcheryDAO.addKachchery(kachchery, user);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }

    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateKachchery(Kachchery kachchery, User user) {
        logger.debug("Updating a Kachchery {}", kachchery.getId());
        /*if (!user.isAuthorized(Permission.LAND_VISIT_SCHEDULE)) {
            handleELandRuntimeException(user.getUsername() + " doesn't have permission to update a kachchery", ErrorCodes.UNAUTHORIZED_ACCESS);
        } else {
            kachcheryDAO.updateKachchery(kachchery, user);
        }*/
        try {
            kachcheryDAO.updateKachchery(kachchery, user);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateAttachDocKachchery(Kachchery kachchery, User user) {
        logger.debug("Updating a Attach DocKachchery {}", kachchery.getId());

        try {
            kachcheryDAO.updateKachchery(kachchery, user);

            if (kachchery.getDocumentList() != null) {
                try {
                    logger.debug("Uploading files");
                    documentManagementService.uploadfiles(user, kachchery.getDocumentList(), kachchery.getId());
                } catch (Exception e) {
                    logger.debug("Error :{}", e);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }

    @Transactional(propagation = Propagation.NEVER, readOnly = true)
    public List<Kachchery> getAllKachcheryByState(Kachchery.Status status) {
        List<Kachchery> kachcheryList = kachcheryDAO.getAllKachcheryByState(status);
        if (kachcheryList != null && kachcheryList.size() > 0) {
            return kachcheryList;
        }
        return Collections.emptyList();
    }

    @Transactional(propagation = Propagation.NEVER, readOnly = true)
    public List<Kachchery> getAllKachcheryByDSDivisionAndState(Kachchery.Status status, User user) {
        logger.debug("Listing  kachchery of D.S. Division by{} ", user.getUsername());
        List<Kachchery> kachcheryList = kachcheryDAO.getAllKachcheryByDSDivisionAndState(status, user);
        if (kachcheryList != null && kachcheryList.size() > 0) {
            return kachcheryList;
        }
        return Collections.emptyList();
    }

    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Kachchery getKachcheryById(long id) {
        return kachcheryDAO.getKachcheryById(id);
    }

    @Transactional(propagation = Propagation.NEVER, readOnly = true)
    public List<LandAssociationDetails> getLandListByKachcheryId(long id) {

        List<LandAssociationDetails> landAssociationDetailsList = new ArrayList<LandAssociationDetails>();
        Kachchery kachchery = kachcheryDAO.getKachcheryById(id);
        if (kachchery != null) {
            Set<LandAssociation> landAssociationSet = kachchery.getLandAssociationList();

            if (landAssociationSet != null) {

                Iterator<LandAssociation> associationIterator = landAssociationSet.iterator();
                while (associationIterator.hasNext()) {
                    LandAssociation association = associationIterator.next();
                    if (association != null) {

                        LandAssociationDetails details = new LandAssociationDetails();
                        details.setId(association.getLand().getId());
                        details.setNameOfTheLand(association.getLand().getNameOfTheLand());

                        List<Integer> ids = new ArrayList<Integer>();
                        for (AlienationMethod am : association.getAlienationMethods()) {
                            logger.debug("\n{}", am.getId());
                            ids.add(am.getId());
                            if (am.getId() == 1) {
                                details.setLandPermit(1);
                            } else if (am.getId() == 2) {
                                details.setLandGrant(1);
                            } else if (am.getId() == 3) {
                                details.setShortTerm(1);
                            } else if (am.getId() == 4) {
                                details.setLongTerm(1);
                            } else if (am.getId() == 5) {
                                details.setDep(1);
                            } else if (am.getId() == 6) {
                                details.setVesting(1);
                            } else if (am.getId() == 7) {
                                details.setSpecial(1);
                            }
                        }
                        details.setAlienationMethods(ids);
                        landAssociationDetailsList.add(details);

                    }

                }

            }
        }

        return landAssociationDetailsList;
    }

    private void handleELandRuntimeException(String message, int code) {
        logger.error(message);
        throw new ELandRuntimeException(message, code);
    }


}
